/*
 *   This file is part of <open-parametrics>
 *   Copyright (c) 2006-2008 Miguel-Angel Sicilia
 *
 *   open-parametrics is free software: you can redistribute it and/or modify
 *   it under the terms of the Lesser GNU General Public License as
 *   published by the Free Software Foundation, either version 3 of
 *   the License, or (at your option) any later version.
 *
 *   open-parametrics is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with open-parametrics.  If not, see <http://www.gnu.org/licenses/>.
 */
package es.uah.cc.ie.parametrics.segmented.cluster;

import es.uah.cc.ie.parametrics.ArffDataset;
import es.uah.cc.ie.parametrics.CostDriver;
import es.uah.cc.ie.parametrics.Dataset;
import es.uah.cc.ie.parametrics.Variable;
import es.uah.cc.ie.parametrics.CERGenerator;
import es.uah.cc.ie.parametrics.CostEstimatingRelationship;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import weka.clusterers.EM;
import weka.core.Instances;

/**
 *
 * @author Miguel-Angel Sicilia
 */
public class ClusterBasedSegmentedCERGenerator extends CERGenerator{

    public ClusterBasedSegmentedCERGenerator(String label){
        super(label);
    }



    /**
     * The implementation of the inherited <tt>generate()</tt> method
     * searchs a <tt>SegmentedCER</tt> using the EM clustering algorithm and
     * an exponential model for the CERs of the segments with default
     * quality requirements.<br> Use the other methods of the class to
     * override the defaults.
     *
     * @param x The relevant cost drivers.
     * @param y The cost variable.
     * @param ds The dataset used for the generation of the model
     * @return An instance of <tt>SegmentedCER</tt>
     */
    @Override
    public CostEstimatingRelationship generate(CostDriver[] x, Variable y,
            Dataset ds) {
        // set up default quality parameters:
        HashMap<String, Double> qualityParams = new HashMap<String, Double>();
        qualityParams.put("mmre", new Double(0.25));
        qualityParams.put("pred25", new Double(70));
        // Build the initial non-segmented model:


        // Start the recursive process:
        searchSegmentedModel(x, y, ds, qualityParams, null);
        // Build the segmented model:
        
        return null;
    }

    /**
     *
     * @param x
     * @param y
     * @param ds
     * @param quality
     * @param model
     * @return
     */
    private CostEstimatingRelationship[] searchSegmentedModel(CostDriver[] x, Variable y,
            Dataset ds, HashMap<String, Double> quality,
            CostEstimatingRelationship model){
        assert(ds instanceof ArffDataset);
        ArffDataset dataset = (ArffDataset)ds;

        if (satisfiesQuality(ds, quality, model)){
             CostEstimatingRelationship[] models =  new CostEstimatingRelationship[1];
             models[0]= model;
             return models;
        }else{
            // Cluster the instances:
            EM clusterer = new EM();
            try {
                // TO-DO: Use only the cost drivers passed as parameter in x.
                clusterer.buildClusterer(dataset.getInstances());
            } catch (Exception ex) {
                Logger.getLogger(ClusterBasedSegmentedCERGenerator.class.getName()).log(Level.SEVERE, null, ex);
            }
            // If more than one cluster, recurse.
            if (clusterer.getNumClusters()>1){
                //...
            }

            // Compose the models:
            return null;
        }
    }

    private boolean satisfiesQuality(Dataset ds,
            HashMap<String, Double> quality, CostEstimatingRelationship model){
        if (model==null)
            return false;
        else{
            return false;
        }
    }

    private Dataset[] getSegments(Instances ds, EM clusterer) {
        for (int i = 0; i < ds.numInstances(); i++){
            try {
                System.out.println(clusterer.distributionForInstance(ds.instance(i)));
            } catch (Exception ex) {
                Logger.getLogger(ClusterBasedSegmentedCERGenerator.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return null;
    }
}

